#include "indexer.h"

#include <algorithm>
#include <memory>

#include "glog/logging.h"


Indexer::Indexer(){
  
}

Indexer::~Indexer() {

}

void Indexer::InitFlannIndexer(const cv::Mat& desc_mat,
                               const std::string& index_file,
                               const IndexMethod index_method) {
  using namespace cvflann;
  using namespace cv::flann;
  std::string local_idx_file{index_file};
  cv::flann::IndexParams* index_params = nullptr;
  if (index_method == LSH) {
    index_params = new LshIndexParams{3, 28, 2};
    checks = 8; eps = 0.01;
    local_idx_file += ".LSH";
  } else if (index_method == HCT) {
    index_params = new HierarchicalClusteringIndexParams{8, FLANN_CENTERS_KMEANSPP, 1, 10};
    checks = 8; eps = 0.05;
    local_idx_file += ".HCT";
  } else {
    index_params = new AutotunedIndexParams;// {0.8f, 0.0001f, 0.0f, 1.0f};
    checks = 16; eps = 0.01;
    local_idx_file += ".AUTO";
  }

  if (mIndexer.load(desc_mat, local_idx_file)) {
    LOG(INFO) << "successfully load index from file: " << local_idx_file;
  } else {
    LOG(INFO) << "build index, and save into file: " << local_idx_file;
    mIndexer.build(desc_mat, *index_params, cvflann::FLANN_DIST_HAMMING);
    mIndexer.save(local_idx_file);
  }
  if (index_params!=nullptr) delete index_params;
}

// knn search  k = 2;
void Indexer::KnnSearch(const cv::Mat& desc_mat, cv::Mat& indices, cv::Mat& dists, int k) {
  mIndexer.knnSearch(desc_mat, indices, dists, k, cv::flann::SearchParams{checks, eps});
}

